<?php
class Usuario extends AppModel {
	
	var $displayField = 'login';
	
	var $name = 'Usuario';
	var $validate = array(
		'nome' => array(
			'rule' => 'notEmpty',
			'message' => 'Preencha seu nome completo'
			),
		'login' => array(
			'login' => array(
				'rule' => 'notEmpty',
				'message' => 'Login inválido'
				),
			'unique' => array(
				'rule' => array('checkUnique', 'login'),
				'message' => 'O login já existe. Digite outro.'
				)),
		'email' => array(
			'email' => array(
				'rule' => 'email',
				'message' => 'Email inválido'
				),
			'unique' => array(
				'rule' => array('checkUnique', 'email'),
				'message' => 'O email já existe. Digite outro endereço de email'
				)),
		'senha_clear' => array(
			'length' => array(
				'rule' => array('minLength', '5'),
				'message' => 'Digite uma senha de no mínimo 5 caracteres'
				),
			'repeat_password' => array(
				'rule' => 'checkPassword',
				'message' => 'As senhas não conferem.'
				)),
		'senha_informada' => array(
			'length' => array(
				'rule' => array('minLength', '5'),
				'message' => 'Digite uma senha de no mínimo 5 caracteres'
				),
			'check_old_password' => array(
				'rule' => 'checkOldPassword',
				'message' => 'A senha digitada não confere.'
				)
			)
		);

	var $hasAndBelongsToMany = array(
		'Amigo' => array(
			'className' => 'Usuario',
			'joinTable' => 'usuarios_amigos',
			'foreignKey' => 'usuario_id',
			'associationForeignKey' => 'amigo_id',
			'with' => 'UsuariosAmigo',
			'unique' => true,
		),
	);
	var $hasMany = array(
		'Mensagem' => array(
			'className' => 'Mensagem',
			'foreignKey' => 'usuario_id',
			'dependent' => false,
			'conditions' => '',
			'fields' => '',
			'order' => '',
			'limit' => '',
			'offset' => '',
			'exclusive' => '',
			'finderQuery' => '',
			'counterQuery' => ''
		),
		'Noticia' => array(
			'className' => 'Noticia',
			'foreignKey' => 'usuario_id',
			'dependent' => false,
			'conditions' => '',
			'fields' => '',
			'order' => '',
			'limit' => '',
			'offset' => '',
			'exclusive' => '',
			'finderQuery' => '',
			'counterQuery' => ''
		)
	);
	public function addFriend($requestingUser, $requestedFriend) {
		if ($status = $this->isFriend($requestingUser, $requestedFriend, true)) {
			if ($status == UsuariosAmigo::ACCEPTED_FRIENDSHIP) {
				throw new DomainException('Ja sao amigos');
			} else if ($status == UsuariosAmigo::PENDING_ACCEPT ) {
				$this->acceptInvite($requestingUser, $requestedFriend);
				throw new LogicException('Você adicionou um novo amigo. Espere o aceite do usuário.');
			} else if($status == UsuariosAmigo::REJECTED){
				//Mensagem 'falsa'. Nada acontecerá mas o usuário não saberá que está bloqueado.
				throw new DomainException('Você adicionou um novo amigo. Espere o aceite do usuário.');
			}
		}

		return (bool) $this->UsuariosAmigo->save(array('usuario_id' => $requestingUser, 'amigo_id' => $requestedFriend));
	}

	function getActivationHash() {
		if(!isset($this->id)){
			return false;
		} 
		return substr(Security::hash(Configure::read('Security.salt') . date('dmY')), 0, 8);
	}
	
	function isFriend($requestingUser, $requestedFriend, $returnStatus = false) {
		$conditions = array(
			'OR' => array(
				array('usuario_id' => $requestingUser, 'amigo_id' => $requestedFriend),
				array('amigo_id' => $requestingUser, 'usuario_id' => $requestedFriend),
			)
		);

		$areFriends = $this->UsuariosAmigo->field('status', $conditions);

		if ($returnStatus) {
			return $areFriends;
		}
		return $areFriends == UsuariosAmigo::ACCEPTED_FRIENDSHIP;
	}
	
	
	function invites($id) {
		return $this->UsuariosAmigo->find('all', array(
				'contain' => array('Usuario'),
				'conditions' => array(
					'UsuariosAmigo.amigo_id' => $id,
					'UsuariosAmigo.status' => UsuariosAmigo::PENDING_ACCEPT
				)
		));
	}
	
	function acceptInvite($requestedFriend, $requestingUser, $accept = true) {
		$conditions = array(
			'amigo_id' => $requestedFriend,
			'usuario_id' => $requestingUser,
			'status' => UsuariosAmigo::PENDING_ACCEPT
		);
		
		$retorno =  $this->UsuariosAmigo->find('first', compact('conditions') + array('fields' => array('id')));
		if ($retorno) {
			$value = $accept ? UsuariosAmigo::ACCEPTED_FRIENDSHIP : UsuariosAmigo::REJECTED;
			$this->UsuariosAmigo->id = $retorno['UsuariosAmigo']['id'];
		  	return (bool) $this->UsuariosAmigo->saveField('status', $value);
		}
		//Arrumar isso pq está com pau (criar o try e catch)
		throw new OutOfBoundException('Solicitação de amigo inválida');
	}
	
	function haveUnblockPermission($requestedFriend, $requestingUser){
		return $this->UsuariosAmigo->find('first', array('conditions' => array('usuario_id' => $requestingUser, 'amigo_id' => $requestedFriend),
																	  'fields' => array('id')));
	}
	
	function checkPassword($data) {
		/* Entra aqui se a requisição vem da action EDIT */
		if(isset($this->data['Usuario']['id'])){
			if($this->data['Usuario']['senhahashed'] == $this->data['Usuario']['senha2hashed'])
				return TRUE;
			else
				return FALSE;
		} else{
			/* Entra aqui se a requisição vem da action ADD */
			if($this->data['Usuario']['senha'] == $this->data['Usuario']['senha2hashed'])
				return TRUE;
			else
				return FALSE;
		}
	}
	
	function checkOldPassword($data){
		// Teste se a requisição vem do action EDIT
		if(isset($this->data['Usuario']['senha_anterior'])){
			/* Testa se a senha do BD é igual a senha informada pelo usuário */
			if($this->data['Usuario']['senha_anterior'] == $this->data['Usuario']['senha_informada_hashed'])
				return TRUE;
			else
				return FALSE;
		} else {
			// Retorna TRUE para a regra não entrar em vigor quando a requisição vem do action ADD
			return TRUE;
		}
	}
	
	function checkUnique($data, $fieldName) {
		$valid = false;
		if(isset($fieldName) && $this->hasField($fieldName)){
			$valid = $this->isUnique(array($fieldName => $data));
		}
		return $valid;
	}

}